//
//  CPADataBaseManager.m
//  CloudPhotoAlbumSDK
//
//  Created by 瞿衡 on 16/12/2.
//  Copyright © 2016年 ND. All rights reserved.
//

#import "BZDataBaseManager.h"
#import "BZDataBase.h"
#import <FMDB/FMDB.h>
#import <objc/runtime.h>
#import <BZPreHeaderComponent/BZPreHeaderComponent.h>

@implementation BZDataBaseManager


+ (FMDatabaseQueue *)initialDbByName:(NSString *)dbName
                          tableNames:(NSArray <NSString *>*)tableNames
                       tableVersions:(NSArray *)tableVersions
                         tableModels:(NSArray *)tableModels
                            outError:(NSError *__autoreleasing *)outError{

    return [[BZDataBase shareDataBase]initialDbByName:dbName
                                           tableNames:tableNames
                                        tableVersions:tableVersions
                                          tableModels:tableModels
                                             outError:outError];

}


#pragma mark ----------------------------------------------------UPDATE------------------------------------------------

+ (void)updateDataBaseByModelAsync:(id)model
                            dbName:(NSString *)dbName
                         tableName:(NSString *)tableName
                      conditionSql:(NSString *)conditionSql
                           success:(void (^)(BOOL bSucced))success
                           failure:(void (^)(NSError *error))failure{

    dispatch_queue_t zzfQueue = dispatch_queue_create("com.cn.zzf.dbQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(zzfQueue, ^{
        
        NSError *error = nil;
        
        BOOL sucessed  = [self updateDataBaseByModelSync:model
                                                  dbName:dbName
                                               tableName:tableName
                                         sqlConditionStr:conditionSql
                                                outError:&error];
        
        if (!error && success) {
            success(sucessed);
        }else{
            if (failure) {
                failure(error);
            }
        }
    });
}




+ (BOOL)updateDataBaseByModelSync:(id)model
                           dbName:(NSString *)dbName
                        tableName:(NSString *)tableName
                  sqlConditionStr:(NSString *)conditionSql
                         outError:(NSError *__autoreleasing *)outError{
    
    unsigned int count       = 0;
    Ivar *members            = class_copyIvarList([model class],&count);
    NSMutableArray *valueArr = [NSMutableArray array];
    NSString *tableSql       = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (",tableName] ;
    //遍历属性列表
    
    for (int i = 0 ; i < count; i++) {

        Ivar var = members[i];
        const char *memberName  = ivar_getName(var);
        const char *memeberType = ivar_getTypeEncoding(var);
        NSString *nameStr = [NSString stringWithCString:memberName encoding:NSUTF8StringEncoding];
        NSString *typeStr = [NSString stringWithCString:memeberType encoding:NSUTF8StringEncoding];
        NSCharacterSet *characterset = [NSCharacterSet characterSetWithCharactersInString:@"_"];
        nameStr  = [nameStr stringByTrimmingCharactersInSet:characterset];
        typeStr  = [typeStr stringByTrimmingCharactersInSet:characterset];
        id value = [model valueForKey:nameStr];

        if ([typeStr isEqualToString:@"@\"NSString\""]) {
            if (value) {
                value = [NSString stringWithFormat:@"'%@'",value];
            }
        }
        if (value) {
            [valueArr addObject:value];
            tableSql = [NSString stringWithFormat:@"%@%@,",tableSql,nameStr];
        }else{
            BZLog(@"typeStr=%@",typeStr);
        }
    }
    
    NSUInteger valueCount = valueArr.count;
    tableSql = [tableSql stringByReplacingCharactersInRange:NSMakeRange(tableSql.length-1,1) withString:@""];
    tableSql = [NSString stringWithFormat:@"%@) VALUES (",tableSql];
    
    for (NSUInteger i = 0 ; i < valueCount; i++) {
        
        if (i == valueCount - 1) {
            
            tableSql = [NSString stringWithFormat:@"%@%@)",tableSql,valueArr[i]];

        }else{
        
            tableSql = [NSString stringWithFormat:@"%@%@,",tableSql,valueArr[i]];
        }
    }

   __block BOOL success = NO;
    FMDatabaseQueue *dbQueue = [[BZDataBase shareDataBase]getDbQueueWithDbName:dbName];
    [dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
      success =  [db executeUpdate:tableSql];
    }];
    
    return success;
}


+ (NSDictionary *)selectDataBaseSync:(NSString *)dbName
                        tableName:(NSString *)tableName
                  sqlConditionStr:(NSString *)conditionSql
                         outError:(NSError *__autoreleasing *)outError{

    NSParameterAssert(dbName);
    NSParameterAssert(tableName);
    
    FMDatabaseQueue *dbQueue       = [[BZDataBase shareDataBase]getDbQueueWithDbName:dbName];
    
    NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
    NSString *tableSql = nil;
    if (conditionSql) {
        tableSql = [NSString stringWithFormat:@"SELECT * FROM %@ %@",tableName,conditionSql];
    }else{
        tableSql = [NSString stringWithFormat:@"SELECT * FROM %@",tableName];
    }
    
    [dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
    
        FMResultSet *result = [db executeQuery:tableSql];
        
        while ([result next]) {
            
            NSUInteger count = result.columnCount;
            for (int i = 0 ; i < count; i++) {
                
                 id value = [result objectForColumnIndex:i];
                 NSString *name = [result columnNameForIndex:i];
                if ([name length] && value) {
                    [dict setObject:value forKey:name];
                }
            }
        }
        [result close];
    }];
    
    return dict;

}



+ (BOOL)deleteDataBaseBySync:(NSString *)dbName
                   tableName:(NSString *)tableName
                  sqlConditionStr:(NSString *)conditionSql
                         outError:(NSError *__autoreleasing *)outError{
    
    
    FMDatabaseQueue *dbQueue       = [[BZDataBase shareDataBase]getDbQueueWithDbName:dbName];
    NSString *tableSql             = [NSString stringWithFormat:@"DELETE FROM %@ %@",tableName,conditionSql];
    __block BOOL success           = NO;
    
    [dbQueue inDatabase:^(FMDatabase *db) {
        
        success = [db executeUpdate:tableSql];
        
    }];
    return success;
}



@end
